package com.ukefu.webim.web.handler.apps.service;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import com.ukefu.core.UKDataContext;
import com.ukefu.util.Menu;
import com.ukefu.util.UKTools;
import com.ukefu.util.bi.CubeReportData;
import com.ukefu.util.bi.UKExcelUtil;
import com.ukefu.util.bi.model.FirstTitle;
import com.ukefu.util.bi.model.Level;
import com.ukefu.util.bi.model.ValueData;
import com.ukefu.webim.service.acd.ServiceQuene;
import com.ukefu.webim.service.es.ContactsRepository;
import com.ukefu.webim.service.es.OnlineUserESRepository;
import com.ukefu.webim.service.impl.AgentUserService;
import com.ukefu.webim.service.impl.CallOutQuene;
import com.ukefu.webim.service.repository.AgentServiceRepository;
import com.ukefu.webim.service.repository.AgentUserContactsRepository;
import com.ukefu.webim.service.repository.AgentUserRepository;
import com.ukefu.webim.service.repository.AgentUserTaskRepository;
import com.ukefu.webim.service.repository.ChatMessageRepository;
import com.ukefu.webim.service.repository.JobDetailRepository;
import com.ukefu.webim.service.repository.OnlineUserHisRepository;
import com.ukefu.webim.service.repository.OnlineUserRepository;
import com.ukefu.webim.service.repository.OrganRepository;
import com.ukefu.webim.service.repository.ServiceSummaryRepository;
import com.ukefu.webim.service.repository.SessionTypeRepository;
import com.ukefu.webim.service.repository.SysDicRepository;
import com.ukefu.webim.service.repository.TagRelationRepository;
import com.ukefu.webim.service.repository.TagRepository;
import com.ukefu.webim.service.repository.UserRepository;
import com.ukefu.webim.service.repository.WeiXinUserRepository;
import com.ukefu.webim.web.handler.Handler;
import com.ukefu.webim.web.model.AgentService;
import com.ukefu.webim.web.model.AgentServiceSummary;
import com.ukefu.webim.web.model.AgentUser;
import com.ukefu.webim.web.model.AgentUserContacts;
import com.ukefu.webim.web.model.AgentUserTask;
import com.ukefu.webim.web.model.JobDetail;
import com.ukefu.webim.web.model.MonitorCallout;
import com.ukefu.webim.web.model.OnlineUser;
import com.ukefu.webim.web.model.SessionConfig;
import com.ukefu.webim.web.model.SessionType;
import com.ukefu.webim.web.model.SysDic;
import com.ukefu.webim.web.model.WeiXinUser;

@Controller
@RequestMapping("/apps/monitor")
public class MonitorServiceController extends Handler{
	
	@Autowired
	private AgentServiceRepository agentServiceRes ;
	
	@Autowired
	private OrganRepository organRes ;
	
	@Autowired
	private UserRepository userRes ;
	
	@Autowired
	private OnlineUserESRepository onlineUserESRes; 
	
	@Autowired
	private OnlineUserRepository onlineUserRes; 
	
	@Autowired
	private ServiceSummaryRepository serviceSummaryRes; 
	
	@Autowired
	private OnlineUserHisRepository onlineUserHisRes;
	
	@Autowired
	private WeiXinUserRepository weiXinUserRes;
	
	@Autowired
	private TagRepository tagRes ;
	
	@Autowired
	private TagRelationRepository tagRelationRes ;
	
	@Autowired
	private ChatMessageRepository chatMessageRepository ;
	
	@Autowired
	private ContactsRepository contactsRes ;
	
	@Autowired
	private AgentUserContactsRepository agentUserContactsRes ;
	
	@Autowired
	private SessionTypeRepository sessionTypeRes ;
	
	@Autowired
	private SysDicRepository sysDicRes ;
	
	@Autowired
	private AgentUserService agentUserRes ;
	
	@Autowired
	private AgentUserRepository agentUserRepository;
	
	@Autowired
	private AgentUserTaskRepository agentUserTaskRes;
	
	@Autowired
	private JobDetailRepository jobDetailRes;
	
	@Value("${web.upload-path}")
    private String path;
	
	
	@RequestMapping("/index")
    @Menu(type = "servicemonitor" , subtype = "index" )
    public ModelAndView index(ModelMap map , HttpServletRequest request ,final String status ,final boolean showsensitive ,final boolean showtimeout,final boolean showinquenetimeout) {
		if (UKTools.getSystemConfig().isMonitor()) {
			this.desktop(map, request, status,showsensitive,showtimeout,showinquenetimeout) ;
		}
        return request(super.createAppsTempletResponse("/apps/service/monitor/index"));
    }
	
	public List<MonitorCallout> getAgentList(final String actid,Date begindate,Date enddate,String orgi){
		List<MonitorCallout> agentList = new ArrayList<>();
		if (UKTools.getSystemConfig().isMonitor()) {
			List<Object> result1 = onlineUserRes.aggrAgentGroupbyUsername(begindate,enddate,orgi,actid);
			if (result1 != null && result1.size() > 0) {
				for(Object re : result1){
					Object[] res = (Object[]) re;
					MonitorCallout mc = new MonitorCallout();
					mc.setUsertype("agent");
					mc.setUsername(res[0].toString());
					mc.setCallouttotal(res[1].toString());
					mc.setTransdurationavg(res[2].toString());
					if (res[3]!=null && !StringUtils.isBlank(res[3].toString())) {
						if (!res[3].toString().equals("0")) {
							mc.setTransdurationsum(UKTools.getDuration(0, Long.parseLong(res[3].toString())));
						}else{
							mc.setTransdurationsum("0");
						}
					}
					mc.setAiringdurationavg(res[4].toString());
					mc.setAiasrtimessum(res[5].toString());
					mc.setAiasrtimesavg(res[6].toString());
					mc.setQualitytotal(res[7].toString());
					mc.setQualitysuccess(res[8].toString());
					mc.setQualityfail(res[9].toString());
					mc.setQualityno(res[10].toString());
					mc.setQualityshold(res[11].toString());
					mc.setAgentdurationavg(res[12].toString());
					mc.setInvitation(res[13].toString());
					mc.setInvitationtotal(res[14].toString());
					if (mc.getQualitytotal()!="" && !mc.getQualitytotal().equals("0") &&
							mc.getQualityshold()!="" && !mc.getQualityshold().equals("0")) {
						mc.setQualitypre(new DecimalFormat("0.00").format((Double.valueOf(mc.getQualitytotal())/Double.valueOf(mc.getQualityshold()))*100));
					}else{
						mc.setQualitypre("0");
					}
					agentList.add(mc);
				}
			}
		}
		return agentList;
	}
	
	public List<MonitorCallout> getAiList(final String actid,Date begindate,Date enddate,String orgi){
		List<MonitorCallout> aiList = new ArrayList<>();
		if (UKTools.getSystemConfig().isMonitor()) {
			List<Object> result2 = onlineUserRes.aggrAgentGroupbyAiAgent(begindate,enddate, orgi,actid);
			if (result2 != null && result2.size() > 0) {
				for(Object re : result2){
					Object[] res = (Object[]) re;
					MonitorCallout mc = new MonitorCallout();
					mc.setUsertype("ai");
					mc.setUsername(res[0].toString());
					mc.setAitotal(res[1].toString());
					mc.setTranstotal(res[2].toString());
					mc.setAitransdurationavg(res[3].toString());
					mc.setAidurationavg(res[4]!=null ? res[4].toString():"0");
					mc.setAiringdurationavg(res[5].toString());
					if (res[6]!=null && !StringUtils.isBlank(res[6].toString())) {
						if (!res[6].toString().equals("0")) {
//						mc.setAidurationsum(new DecimalFormat("0.00").format(Double.valueOf(res[6].toString())/3600000));
							mc.setAidurationsum(UKTools.getDuration(0, Long.parseLong(res[6].toString())));
						}else{
							mc.setAidurationsum("0");
						}
					}
					mc.setAiasrtimessum(res[7].toString());
					mc.setAiasrtimesavg(res[8]!=null ? res[8].toString():"0");
					mc.setAicutin(res[9].toString());
					aiList.add(mc);
				}
			}
		}
		return aiList;
	}
	
	/**
	 * 外呼监控
	 */
	@RequestMapping("/callout")
    @Menu(type = "servicemonitor" , subtype = "callout" )
    public ModelAndView callout(ModelMap map , HttpServletRequest request ,final String actid,String begin,String end) throws ParseException {
		this.calloutdesktop(map, request, actid, begin, end) ;
        return request(super.createAppsTempletResponse("/apps/service/monitor/callout/index"));
    }
	
	/**
	 * 人工坐席监控
	 */
	@RequestMapping("/agent")
    @Menu(type = "servicemonitor" , subtype = "agent" )
    public ModelAndView agent(ModelMap map , HttpServletRequest request ,final String actid,String begin,String end) throws ParseException  {
		this.agentdesktop(map, request, actid,begin, end) ;
	
        return request(super.createAppsTempletResponse("/apps/service/monitor/agent/index"));
    }
	
	/**
	 * 外呼机器人监控
	 */
	@RequestMapping("/ai")
    @Menu(type = "servicemonitor" , subtype = "ai" )
    public ModelAndView ai(ModelMap map , HttpServletRequest request ,final String actid,final String begin,final String end) throws ParseException {
		this.aidesktop(map, request, actid,begin,  end) ;
		
        return request(super.createAppsTempletResponse("/apps/service/monitor/ai/index"));
    }
	
	/**
	 * 预览式外呼监控
	 */
	@RequestMapping("/agentcall")
    @Menu(type = "servicemonitor" , subtype = "agentcall" )
    public ModelAndView agentcall(ModelMap map , HttpServletRequest request ,final String actid,final String begin,final String end) throws ParseException {
		this.agentcalldesktop(map, request, actid,begin,  end) ;
		
        return request(super.createAppsTempletResponse("/apps/service/monitor/agentcall/index"));
    }
	
	/**
	 * 预测式外呼监控
	 */
	@RequestMapping("/forecast")
    @Menu(type = "servicemonitor" , subtype = "forecast" )
    public ModelAndView forecast(ModelMap map , HttpServletRequest request ,final String actid,final String begin,final String end) throws ParseException {
		this.forecastdesktop(map, request, actid,begin,  end) ;
		
        return request(super.createAppsTempletResponse("/apps/service/monitor/forecast/index"));
    }
	
	
	
	@RequestMapping("/online/index")
    @Menu(type = "servicemonitor" , subtype = "index" )
    public ModelAndView online(ModelMap map , HttpServletRequest request , final String userid , String agentservice , @Valid String channel) {
		if(!StringUtils.isBlank(userid) && UKTools.getSystemConfig().isMonitor()){
			map.put("inviteResult", UKTools.getWebIMInviteResult(onlineUserRes.findByOrgiAndUserid(super.getOrgi(request), userid))) ;
			map.put("tagRelationList", tagRelationRes.findByUseridAndOrgi(userid,super.getOrgi(request))) ;
			map.put("onlineUserHistList", onlineUserHisRes.findByUseridAndOrgi(userid, super.getOrgi(request))) ;
			map.put("agentServicesAvg", onlineUserRes.countByUserForAvagTime(super.getOrgi(request), UKDataContext.AgentUserStatusEnum.END.toString(),userid)) ;
			
			//List<AgentService> agentServiceList = agentServiceRes.findByUseridAndOrgi(userid, super.getOrgi(request)) ; 
			final String orgi = super.getOrgi(request);
			Page<AgentService> agentServiceList= agentServiceRes.findAll(new Specification<AgentService>(){
				@Override
				public Predicate toPredicate(Root<AgentService> root, CriteriaQuery<?> query,
						CriteriaBuilder cb) {
					List<Predicate> list = new ArrayList<Predicate>();  
					list.add(cb.equal(root.get("orgi").as(String.class), orgi));
					list.add(cb.equal(root.get("userid").as(String.class),userid));
					
					Predicate[] p = new Predicate[list.size()];  
					return cb.and(list.toArray(p));   
				}}, new PageRequest(0, 10000, Sort.Direction.DESC, new String[] { "servicetime" }));
			
			map.put("agentServiceList", agentServiceList) ;
			if(agentServiceList.getContent().size()>0){
				map.put("serviceCount", Integer
						.valueOf(this.agentServiceRes
								.countByUseridAndOrgiAndStatus(userid, super.getOrgi(request),
										UKDataContext.AgentUserStatusEnum.END.toString())));
				
				AgentService agentService = agentServiceList.getContent().get(0) ;
				if(!StringUtils.isBlank(agentservice)){
					for(AgentService as : agentServiceList.getContent()){
						if(as.getId().equals(agentservice)){
							agentService = as ; break ;
						}
					}
				}
				
				if(agentService!=null){
					Page<AgentServiceSummary> summaryList = this.serviceSummaryRes.findByOrgiAndUserid(super.getOrgi(request), userid , new PageRequest(0, super.getPs(request), Sort.Direction.DESC, new String[] { "createtime" }));
					map.addAttribute("summaryList", summaryList) ;
					map.addAttribute("tagsSummary", tagRes.findByOrgiAndTagtype(super.getOrgi(request) , UKDataContext.ModelType.SUMMARY.toString())) ;
				}
				
				List<AgentUserContacts> agentUserContactsList = agentUserContactsRes.findByUseridAndOrgi(userid, super.getOrgi(request)) ;
				if(agentUserContactsList.size() > 0){
					AgentUserContacts agentUserContacts = agentUserContactsList.get(0) ;
					map.put("contacts", contactsRes.findByIdAndOrgi(agentUserContacts.getContactsid(),super.getOrgi(request))) ;
				}
				
				map.put("tags", tagRes.findByOrgiAndTagtype(super.getOrgi(request) , UKDataContext.ModelType.USER.toString())) ;
				map.put("curAgentService", agentService) ;
				
				
				map.put("agentUserMessageList", chatMessageRepository.findByAgentserviceidAndOrgi(agentService.getId() , super.getOrgi(request), new PageRequest(0, 50, Direction.DESC , "updatetime")));
			}
			
			if(UKDataContext.ChannelTypeEnum.WEIXIN.toString().equals(channel)){
				List<WeiXinUser> weiXinUserList = weiXinUserRes.findByOpenidAndOrgi(userid, super.getOrgi(request)) ;
				if(weiXinUserList.size() > 0){
					WeiXinUser weiXinUser = weiXinUserList.get(0) ;
					map.put("weiXinUser",weiXinUser);
				}
			}else if(UKDataContext.ChannelTypeEnum.WEBIM.toString().equals(channel)){
				List<OnlineUser> onlineUserList =  onlineUserESRes.findByUseridAndOrgi(userid, super.getOrgi(request)) ;
				if(onlineUserList.size() >0){
					map.put("onlineUser", onlineUserList.get(0)) ;
				}
			}
			map.put("agentUser", agentUserRes.findByUseridAndOrgi(userid, super.getOrgi(request))) ;
			map.put("curagentuser", agentUserRes.findByUseridAndOrgi(userid, super.getOrgi(request))) ;
			map.put("monitoragentuser", agentUserTaskRes.findByUseridAndOrgi(userid, super.getOrgi(request))) ;
			
			//文字客服
			AgentService agentService = agentServiceRes.findByIdAndOrgi(agentservice, super.getOrgi(request));
			SysDic sysDic = sysDicRes.findByCode("sessionWords");
			if(agentService != null &&sysDic != null){
				List<SessionType> sessionTypeList = sessionTypeRes.findByOrgiAndCtype(super.getOrgi(request), sysDic.getId());
				for(SessionType  ses : sessionTypeList){
					if(!StringUtils.isBlank(agentService.getSessiontype()) && ses.getId().equals(agentService.getSessiontype())){
						map.addAttribute("agentSessionType", ses.getName());
					}
				}
			}
			map.addAttribute("agentService", agentService);
			map.addAttribute("userid", userid);
			map.addAttribute("agentservice", agentservice);
			map.addAttribute("channel", channel);
		}
		SessionConfig sessionConfig = ServiceQuene.initSessionConfig(super.getOrgi(request)) ;
    	map.put("sessionConfig", sessionConfig) ;
        return request(super.createRequestPageTempletResponse("/apps/service/monitor/agent"));
    }
	
	@RequestMapping({ "/agent/end" })
	@Menu(type = "service" , subtype = "index" )
	public ModelAndView end(HttpServletRequest request, @Valid String userid)
			throws Exception {
		AgentUser agentUser = agentUserRepository.findByIdAndOrgi(userid, super.getOrgi(request));
		if(agentUser!=null && super.getUser(request).getId().equals(agentUser.getAgentno())){
			ServiceQuene.deleteAgentUser(agentUser, super.getOrgi(request) , UKDataContext.EndByType.AGENT.toString());
			if(!StringUtils.isBlank(agentUser.getAgentserviceid())){
				AgentService agentService = agentServiceRes.findByIdAndOrgi(agentUser.getAgentserviceid(), super.getOrgi(request)) ;
				if(agentService!=null) {
					agentService.setStatus(UKDataContext.AgentUserStatusEnum.END.toString());
					agentServiceRes.save(agentService) ;
				}
			}
		}
		return request(super
				.createRequestPageTempletResponse("redirect:/apps/monitor/index.html"));
	}
	
	@RequestMapping("/desktop")
    @Menu(type = "service" , subtype = "index" )
    public ModelAndView desktop(ModelMap map , HttpServletRequest request ,final String status ,final boolean showsensitive ,final boolean showtimeout,final boolean showinquenetimeout) {
		if (UKTools.getSystemConfig().isMonitor()) {
			final String orgi = super.getOrgi(request);
			SessionConfig sessionConfig = ServiceQuene.initSessionConfig(super.getOrgi(request)) ;
			Page<AgentUserTask> page = null ;
			if (!showinquenetimeout) {
				page = agentUserTaskRes.findAll(new Specification<AgentUserTask>(){
					@Override
					public Predicate toPredicate(Root<AgentUserTask> root, CriteriaQuery<?> query,CriteriaBuilder cb) {
						List<Predicate> list = new ArrayList<Predicate>();  
						if (!showsensitive && !showtimeout && !showinquenetimeout) {
							if(!StringUtils.isBlank(status)) {
								list.add(cb.equal(root.get("status").as(String.class), status)) ;
							}else {
								//咨询中的会话
								list.add(cb.equal(root.get("status").as(String.class), UKDataContext.AgentUserStatusEnum.INSERVICE.toString())) ;
							}
						}
						if (showsensitive) {
							//触发敏感词的会话
							list.add(cb.notEqual(root.get("agentfrewords").as(int.class), 0)) ;
							//list.add(cb.or(cb.notEqual(root.get("agentfrewords").as(int.class), 0), cb.notEqual(root.get("servicefrewords").as(int.class), 0))) ;
						}
						if (showtimeout) {
							//会话超时的会话
							list.add(cb.lessThan(root.get("servicetime").as(Date.class), UKTools.getLastTime(ServiceQuene.initSessionConfig(orgi).getSestimeouts()))) ;
							list.add(cb.equal(root.get("status").as(String.class), UKDataContext.AgentUserStatusEnum.INSERVICE.toString())) ;
						}
						
						list.add(cb.equal(root.get("orgi").as(String.class), orgi)) ;
						
						
						Predicate[] p = new Predicate[list.size()];  
						return cb.and(list.toArray(p));   
					}
				},new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime")) ;
			}else {
				//排队超时的会话
				page = onlineUserRes.findByInquenetimeoutFromAgentUserTask(sessionConfig.getInquenetimeouts(),orgi,new PageRequest(super.getP(request), super.getPs(request), Direction.DESC , "createtime"));
			}
			
			map.put("showsensitive", showsensitive) ;
			map.put("showtimeout", showtimeout) ;
			map.put("showinquenetimeout", showinquenetimeout) ;
			
			map.put("agentServiceList", page) ;
			map.put("organlist",organRes.findByOrgi(super.getOrgi(request)));
			map.put("userlist",userRes.findByOrgiAndDatastatus(super.getOrgi(request), false));
			map.put("status",StringUtils.isNotBlank(status) ? status : UKDataContext.AgentUserStatusEnum.INSERVICE.toString());
			Map<String,Long> agentUserTaskCount = onlineUserRes.countAgentUserTask(super.getOrgi(request)) ;
			//底下
			long inservicecount = agentUserTaskCount.get("inservicecount");//咨询中的会话
			long inquenecount = agentUserTaskCount.get("inquenecount");//等待接入的会话
			long frewordscount = agentUserTaskCount.get("frewordscount");//坐席敏感词报警的会话
			map.put("monitorcount", inservicecount+inquenecount) ; //监控会话数量
			map.put("inservicecount", inservicecount) ;
			map.put("inquenecount",inquenecount) ;
			map.put("frewordscount",frewordscount) ;
			
			//上方
			long agentfrewordssum = agentUserTaskCount.get("agentfrewordssum")==null?0L:agentUserTaskCount.get("agentfrewordssum");//坐席敏感词报警
			long servicefrewordssum = agentUserTaskCount.get("servicefrewordssum")==null?0L:agentUserTaskCount.get("servicefrewordssum"); //访客敏感词报警
			long msgtimeoutagentsum = agentUserTaskCount.get("msgtimeoutagentsum")==null?0L:agentUserTaskCount.get("msgtimeoutagentsum"); //坐席会话超时次数
			Long avg = onlineUserRes.avgByAvgreplytimeFromAgentUserTask(super.getOrgi(request)) ;
			long avgreplytime = avg ==null?0L:avg.longValue();//平均响应超时时长
			long agentservicetimeoutavg = 0 ;
			long sessiontimeoutsum =0 ;
			if (sessionConfig.isSestimeout()) {
				List<AgentUserTask> timeoutList = agentUserTaskRes.findByServicetimeLessThanAndStatusAndOrgi(UKTools.getLastTime(sessionConfig.getSestimeouts()) ,UKDataContext.AgentUserStatusEnum.INSERVICE.toString(),sessionConfig.getOrgi()) ;
				if (timeoutList != null && timeoutList.size() > 0) {
					for(AgentUserTask aut : timeoutList) {
						agentservicetimeoutavg += (new Date().getTime() -aut.getServicetime().getTime())/1000-sessionConfig.getSestimeouts() ;
					}
					agentservicetimeoutavg = agentservicetimeoutavg/timeoutList.size() ;
				}
//			long agentservicetimeoutavg = onlineUserRes.avgByAgentservicetimeoutFromAgentUserTask(super.getOrgi(request))==null?0L:onlineUserRes.avgByAgentservicetimeoutFromAgentUserTask(super.getOrgi(request));//平均超时时长
//			long sessiontimeoutsum = agentUserTaskCount.get("sessiontimeoutsum")==null?0L:agentUserTaskCount.get("sessiontimeoutsum"); //会话超时次数
				sessiontimeoutsum = (long)timeoutList.size() ; //会话超时次数
			}
			long quenetimeoutcount = 0;
			long queueavg = 0;
			if (sessionConfig.isInquenetimeout()) {
//			先注释掉
				Long qavg = onlineUserRes.avgByQueueavgFromAgentUserTask(super.getOrgi(request)) ; 
				queueavg = qavg ==null?0L:qavg.longValue();//平均排队时长
				Long qcount = onlineUserRes.countByInquenetimeoutFromAgentUserTask(sessionConfig.getInquenetimeouts(),orgi) ;
				quenetimeoutcount = qcount ==null?0L:qcount.longValue();//排队超时次数
			}
			long invalidcount = agentUserTaskCount.get("invalidcount");//无效会话次数
			long queneoutcount = agentUserTaskCount.get("queneoutcount");//访客排队中离开 次数
			long agentoutcount = agentUserTaskCount.get("agentoutcount");//进入会话后离开 次数
			long satisfactionalarmscount = agentUserTaskCount.get("satisfactionalarmscount")==null?0L:agentUserTaskCount.get("satisfactionalarmscount");//满意度报警次数
			long invitevalscount = agentUserTaskCount.get("invitevalscount")==null?0L:agentUserTaskCount.get("invitevalscount");//邀请评价次数
			long resptimeoutscount = agentUserTaskCount.get("resptimeoutscount")==null?0L:agentUserTaskCount.get("resptimeoutscount");//响应超时 次数
			map.put("agentfrewordssum", agentfrewordssum) ;
			map.put("servicefrewordssum", servicefrewordssum) ;
			map.put("msgtimeoutagentsum", msgtimeoutagentsum) ;
			map.put("agentservicetimeoutavg", agentservicetimeoutavg) ;
			map.put("avgreplytime", avgreplytime) ;
			map.put("sessiontimeoutsum", sessiontimeoutsum) ;
			map.put("queueavg", queueavg) ;
			map.put("quenetimeoutcount", quenetimeoutcount) ;
			map.put("invalidcount", invalidcount) ;
			map.put("queneoutcount", queneoutcount) ;
			map.put("agentoutcount", agentoutcount) ;
			map.put("satisfactionalarmscount", satisfactionalarmscount) ;
			map.put("invitevalscount", invitevalscount) ;
			map.put("resptimeoutscount", resptimeoutscount) ;
			map.put("warns", agentfrewordssum+servicefrewordssum+satisfactionalarmscount) ;
			map.put("sessionConfig", sessionConfig) ;
		}
		
        return request(super.createRequestPageTempletResponse("/apps/service/monitor/content"));
    }
	
	@RequestMapping("/callout/desktop")
    @Menu(type = "servicemonitor" , subtype = "callout" )
    public ModelAndView calloutdesktop(ModelMap map , HttpServletRequest request ,final String actid,String begin,String end) throws ParseException {
		Date now = new Date();
		begin =!StringUtils.isBlank(begin)?begin:UKTools.dateFormate.format(UKTools.getStartTime());
		end = !StringUtils.isBlank(end)?end:UKTools.dateFormate.format(UKTools.getNextDay(now,1));
		Date begindate = !StringUtils.isBlank(begin)?UKTools.dateFormate.parse(begin):UKTools.getStartTime();
		Date enddate = !StringUtils.isBlank(end)? UKTools.dateFormate.parse(end):UKTools.getNextDay(now,1);
		List<MonitorCallout> agentList = this.getAgentList(actid, begindate, enddate, super.getOrgi(request));
		map.addAttribute("agentList", agentList);
		List<MonitorCallout> aiList = this.getAiList(actid, begindate, enddate, super.getOrgi(request));
		map.addAttribute("aiList", aiList);
		map.addAttribute("begin", begin);
		map.addAttribute("end", end);
		this.getnow(map, request, actid);
		if (UKTools.getSystemConfig().isMonitor()) {
			this.getnowcall(map, request, actid, begindate, enddate);
		}
        return request(super.createRequestPageTempletResponse("/apps/service/monitor/callout/content"));
    }
	
	@RequestMapping("/agent/desktop")
    @Menu(type = "servicemonitor" , subtype = "agent" )
    public ModelAndView agentdesktop(ModelMap map , HttpServletRequest request ,final String actid,String begin,String end) throws ParseException {
		Date now = new Date();
		begin =!StringUtils.isBlank(begin)?begin:UKTools.dateFormate.format(UKTools.getStartTime());
		end = !StringUtils.isBlank(end)?end:UKTools.dateFormate.format(UKTools.getNextDay(now,1));
		Date begindate = !StringUtils.isBlank(begin)?UKTools.dateFormate.parse(begin):UKTools.getStartTime();
		Date enddate = !StringUtils.isBlank(end)? UKTools.dateFormate.parse(end):UKTools.getNextDay(now,1);
		List<MonitorCallout> agentList = this.getAgentList(actid, begindate, enddate, super.getOrgi(request));
		map.addAttribute("agentList", agentList);
		map.addAttribute("begin", begin);
		map.addAttribute("end", end);
		this.getnow(map, request, actid);
//		this.getnowcall(map, request, actid, begindate, enddate);
		if (UKTools.getSystemConfig().isMonitor()) {
			List<Object> aggrAiRingtime = onlineUserRes.aggrAiRingdurationMonitor(begindate, enddate, super.getOrgi(request), actid);
			Object[] ringresult =aggrAiRingtime!=null && aggrAiRingtime.size()==1 ?(Object[])aggrAiRingtime.get(0):null;
			String sumAiRingtime = ringresult!=null && ringresult.length==2 && ringresult[0]!=null?UKTools.getDuration(0, Long.parseLong(ringresult[0].toString())*1000):"00:00:00" ;
			String avgAiRingtime = ringresult!=null && ringresult.length==2 && ringresult[1]!=null?ringresult[1].toString():"0" ;
			map.addAttribute("sumAiRingtime", sumAiRingtime);//机器人振铃总时长
			map.addAttribute("avgAiRingtime", avgAiRingtime);//机器人振铃平均时长(秒)
		}
        return request(super.createRequestPageTempletResponse("/apps/service/monitor/agent/content"));
    }
	
	@RequestMapping("/ai/desktop")
    @Menu(type = "servicemonitor" , subtype = "ai" )
    public ModelAndView aidesktop(ModelMap map , HttpServletRequest request ,final String actid,String begin,String end) throws ParseException {
		Date now = new Date();
		begin =!StringUtils.isBlank(begin)?begin:UKTools.dateFormate.format(UKTools.getStartTime());
		end = !StringUtils.isBlank(end)?end:UKTools.dateFormate.format(UKTools.getNextDay(now,1));
		Date begindate = !StringUtils.isBlank(begin)?UKTools.dateFormate.parse(begin):UKTools.getStartTime();
		Date enddate = !StringUtils.isBlank(end)? UKTools.dateFormate.parse(end):UKTools.getNextDay(now,1);
		List<MonitorCallout> aiList = this.getAiList(actid, begindate, enddate, super.getOrgi(request));
		map.addAttribute("aiList", aiList);
		map.addAttribute("begin", begin);
		map.addAttribute("end", end);
		this.getnow(map, request, actid);
//		this.getnowcall(map, request, actid, begindate, enddate);
		if (UKTools.getSystemConfig().isMonitor()) {
			List<Object> aggrAiRingtime = onlineUserRes.aggrAiRingdurationMonitor(begindate, enddate, super.getOrgi(request), actid);
			Object[] ringresult =aggrAiRingtime!=null && aggrAiRingtime.size()==1 ?(Object[])aggrAiRingtime.get(0):null;
			String sumAiRingtime = ringresult!=null && ringresult.length==2 && ringresult[0]!=null?UKTools.getDuration(0, Long.parseLong(ringresult[0].toString())*1000):"00:00:00" ;
			String avgAiRingtime = ringresult!=null && ringresult.length==2 && ringresult[1]!=null?ringresult[1].toString():"0" ;
			map.addAttribute("sumAiRingtime", sumAiRingtime);//机器人振铃总时长
			map.addAttribute("avgAiRingtime", avgAiRingtime);//机器人振铃平均时长(秒)
		}
        return request(super.createRequestPageTempletResponse("/apps/service/monitor/ai/content"));
    }
	
	@RequestMapping("/agentcall/desktop")
    @Menu(type = "servicemonitor" , subtype = "agentcall" )
    public ModelAndView agentcalldesktop(ModelMap map , HttpServletRequest request ,final String actid,String begin,String end) throws ParseException {
//		this.getnow( map , request , actid);
		final String orgi = super.getOrgi(request);
		map.addAttribute("jobList", jobDetailRes.findAll(new Specification<JobDetail>(){
			@Override
			public Predicate toPredicate(Root<JobDetail> root, CriteriaQuery<?> query,
					CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<Predicate>();
				list.add(cb.equal(root.get("orgi").as(String.class), orgi));
				list.add(cb.equal(root.get("actype").as(String.class), "agent"));

				Predicate[] p = new Predicate[list.size()];
				return cb.and(list.toArray(p));
			}}));
		map.addAttribute("actid", actid);
		int agentconcurrency = CallOutQuene.countIncallCallCenterAgent(orgi,actid);
		map.addAttribute("agentconcurrency",agentconcurrency);//人工并发总量
		int agentpreviewing = CallOutQuene.countPreviewingCallCenterAgent(orgi,actid);
		map.addAttribute("agentpreviewing",agentpreviewing);
		
		Date now = new Date();
		begin =!StringUtils.isBlank(begin)?begin:UKTools.dateFormate.format(UKTools.getStartTime());
		end = !StringUtils.isBlank(end)?end:UKTools.dateFormate.format(UKTools.getNextDay(now,1));
		Date begindate = !StringUtils.isBlank(begin)?UKTools.dateFormate.parse(begin):UKTools.getStartTime();
		Date enddate = !StringUtils.isBlank(end)? UKTools.dateFormate.parse(end):UKTools.getNextDay(now,1);
		List<MonitorCallout> agentList = this.getAgentList(actid, begindate, enddate, super.getOrgi(request));
		map.addAttribute("agentList", agentList);
		map.addAttribute("begin", begin);
		map.addAttribute("end", end);
//		this.getnowcall(map, request, actid, begindate, enddate);
        return request(super.createRequestPageTempletResponse("/apps/service/monitor/agentcall/content"));
    }
	
	@RequestMapping("/forecast/desktop")
    @Menu(type = "servicemonitor" , subtype = "forecast" )
    public ModelAndView forecastdesktop(ModelMap map , HttpServletRequest request ,final String actid,String begin,String end) throws ParseException {
		this.getnow( map , request , actid);
		final String orgi = super.getOrgi(request);
		map.addAttribute("jobList", jobDetailRes.findAll(new Specification<JobDetail>(){
			@Override
			public Predicate toPredicate(Root<JobDetail> root, CriteriaQuery<?> query,
					CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<Predicate>();
				list.add(cb.equal(root.get("orgi").as(String.class), orgi));
				list.add(cb.equal(root.get("actype").as(String.class), "forecast"));

				Predicate[] p = new Predicate[list.size()];
				return cb.and(list.toArray(p));
			}}));
		map.addAttribute("actid", actid);
		
		Date now = new Date();
		begin =!StringUtils.isBlank(begin)?begin:UKTools.dateFormate.format(UKTools.getStartTime());
		end = !StringUtils.isBlank(end)?end:UKTools.dateFormate.format(UKTools.getNextDay(now,1));
		Date begindate = !StringUtils.isBlank(begin)?UKTools.dateFormate.parse(begin):UKTools.getStartTime();
		Date enddate = !StringUtils.isBlank(end)? UKTools.dateFormate.parse(end):UKTools.getNextDay(now,1);
		List<MonitorCallout> agentList = this.getForecastAgentList(actid, begindate, enddate, super.getOrgi(request));
		map.addAttribute("agentList", agentList);
		List<MonitorCallout> skillList = this.getForecastSkillList(actid, begindate, enddate, super.getOrgi(request));
		map.addAttribute("skillList", skillList);
		map.addAttribute("begin", begin);
		map.addAttribute("end", end);
		this.getForecastnowcall(map, request, actid, begindate, enddate);
        return request(super.createRequestPageTempletResponse("/apps/service/monitor/forecast/content"));
    }
	
	@RequestMapping("/callout/getnow")
    @Menu(type = "servicemonitor" , subtype = "getnow" )
    public ModelAndView getnow(ModelMap map , HttpServletRequest request , String actid) {
		final String orgi = super.getOrgi(request);
		map.addAttribute("jobList", jobDetailRes.findAll(new Specification<JobDetail>(){
			@Override
			public Predicate toPredicate(Root<JobDetail> root, CriteriaQuery<?> query,
					CriteriaBuilder cb) {
				List<Predicate> list = new ArrayList<Predicate>();
				list.add(cb.equal(root.get("orgi").as(String.class), orgi));
				list.add(cb.equal(root.get("actype").as(String.class), "ai"));

				Predicate[] p = new Predicate[list.size()];
				return cb.and(list.toArray(p));
			}}));
		map.addAttribute("actid", actid);
		int totalconcurrency = CallOutQuene.countAiCallOut(orgi,null,actid);
		map.addAttribute("totalconcurrency",totalconcurrency);//外呼并发总数
		int agentconcurrency = CallOutQuene.countIncallCallCenterAgent(orgi,actid);
		map.addAttribute("agentconcurrency",agentconcurrency);//人工并发总量
		int aiconcurrency = 0;
		if(totalconcurrency!=0){
			aiconcurrency=totalconcurrency-CallOutQuene.countIncallActidCallCenterAgent(orgi, actid);//机器人并发总数  = 总-人工(actid非空)
		}
		map.addAttribute("aiconcurrency",aiconcurrency);//机器人并发总数  = 总-人工
		int totalagent = CallOutQuene.countCallCenterAgent(orgi,actid); //总坐席数
		map.addAttribute("totalagent",totalagent);//在线坐席总量
		long noincall = CallOutQuene.countkongxianCallCenterAgent(orgi,actid);
		map.addAttribute("noincall",noincall);//空闲坐席总量
		map.addAttribute("noincallp",noincall!=0?new DecimalFormat("0.00").format(((double)noincall/(double)totalagent)*100):0);//空闲坐席比例
		map.addAttribute("noincallpupdmax", CallOutQuene.maxWaittimeCallCenterAgent(orgi, actid));//空闲坐席最大等待时长(秒)
		map.addAttribute("noincallpupdavg", CallOutQuene.avgWaittimeCallCenterAgent(orgi, actid));//空闲坐席等待平均时长(秒)
		
		map.addAttribute("aiandagent", aiconcurrency!=0 && totalagent!=0 ?new DecimalFormat("0.00").format((double)aiconcurrency/(double)totalagent):-1);//机器人和人工坐席的比例数
		map.addAttribute("aiandagentonincall", aiconcurrency!=0 && agentconcurrency!=0 ?new DecimalFormat("0.00").format((double)aiconcurrency/(double)agentconcurrency):-1);//机器人和人工坐席的比例数(不含空闲)
		
		long sumAgentIncalltime = CallOutQuene.sumIncalltimeCallCenterAgent(orgi, actid);
		map.addAttribute("sumAgentIncalltime", sumAgentIncalltime);//坐席通话总时长
		map.addAttribute("avgAgentIncalltime", sumAgentIncalltime!=0 && agentconcurrency!=0 ? sumAgentIncalltime/agentconcurrency:0);//坐席通话平均时长(秒)
		
		map.addAttribute("sumAiIncalltime", CallOutQuene.sumIncalltimeCallOutNames(orgi, actid));//机器人通话总时长
		map.addAttribute("avgAiIncalltime", CallOutQuene.avgIncalltimeCallOutNames(orgi, actid));//机器人通话平均时长(秒)

		int totalconcurrencyforecast = CallOutQuene.countForecastCallOut(orgi);
		map.addAttribute("totalconcurrencyforecast",totalconcurrencyforecast);//外呼并发总数(预测式外呼)
		
        return request(super.createRequestPageTempletResponse("/apps/service/monitor/include/now"));
    }
	
	@RequestMapping("/callout/getnowcall")
    @Menu(type = "servicemonitor" , subtype = "getnow" )
    public ModelAndView getnowcall(ModelMap map , HttpServletRequest request , String actid,Date begin,Date end) {
		map.addAttribute("actid", actid);
//		String orgi =super.getOrgi(request);
		Map<String,Object> aggrResult = null;
		if (UKTools.getSystemConfig().isMonitor()) {
			if (!StringUtils.isBlank(actid)) {
				aggrResult = onlineUserRes.aggrCallcenterMonitor(begin, end, super.getOrgi(request),actid);
			}else{
				aggrResult = onlineUserRes.aggrCallcenterMonitor(begin, end, super.getOrgi(request));
			}
		}
		if (aggrResult != null) {
			long calltotal = (long)aggrResult.get("calltotal");//通话总量
			map.addAttribute("calltotal", calltotal);
			long answertotal = (long)aggrResult.get("answertotal");//接通总量
			map.addAttribute("answertotal", answertotal);
//			long aiduration = onlineUserRes.sumAidurationMonitor(begin, end, orgi, actid)==null?0:onlineUserRes.sumAidurationMonitor(begin, end, orgi, actid);//机器人通话总时长
			long aiduration =aggrResult.get("sumAidurationMonitor")!=null?(long)aggrResult.get("sumAidurationMonitor"):0;
			map.addAttribute("aiduration", aiduration);
//			long agentduration = onlineUserRes.sumAgentdurationMonitor(begin, end, orgi, actid)==null?0:onlineUserRes.sumAgentdurationMonitor(begin, end, orgi, actid);//转人工通话总时长
			long agentduration =aggrResult.get("sumAgentdurationMonitor")!=null?(long)aggrResult.get("sumAgentdurationMonitor"):0;
			map.addAttribute("agentduration", agentduration);
			long aitranstotal = (long)aggrResult.get("aitranstotal");//转人工总量
			map.addAttribute("aitranstotal", aitranstotal);
//			long waittingtotal = onlineUserRes.sumWaittimeMonitor(begin, end, orgi, actid)==null?0: onlineUserRes.sumWaittimeMonitor(begin, end, orgi, actid);//总等待时长
			long waittingtotal =aggrResult.get("sumWaittimeMonitor")!=null?(long)aggrResult.get("sumWaittimeMonitor"):0;
			map.addAttribute("waittingtotal", waittingtotal);
			long invitationsuccess = (long)aggrResult.get("invitationsuccess");//成功邀约
			map.addAttribute("invitationsuccess", invitationsuccess);
			long transfailds =aggrResult.get("transfailds")!=null?(long)aggrResult.get("transfailds"):0;//转人工失败量
			map.addAttribute("transfailds", transfailds);
//			long transrealfailds =aggrResult.get("transrealfailds")!=null?(long)aggrResult.get("transrealfailds"):0;//真损量
//			map.addAttribute("transrealfailds", transrealfailds);
			long transfakefailds =aggrResult.get("transfakefailds")!=null?(long)aggrResult.get("transfakefailds"):0;//假损量
			map.addAttribute("transfakefailds", transfakefailds);
			long cantrans =aggrResult.get("cantrans")!=null?(long)aggrResult.get("cantrans"):0;//可转人工量
			long transrealfailds = cantrans!=0 ?cantrans-aitranstotal:0;//真损量
			if (transrealfailds<0) {
				transrealfailds = 0;
			}
			map.addAttribute("transrealfailds", transrealfailds);
			long sumAiRingtime = aggrResult.get("sumringduration")!=null?(long)aggrResult.get("sumringduration"):0;//机器人振铃总时长
			map.addAttribute("sumAiRingtime", sumAiRingtime!=0?UKTools.getDuration(0, sumAiRingtime*1000):"00:00:00");//机器人振铃总时长
			Double avgAiRingtime = aggrResult.get("avgringduration")!=null?(Double)aggrResult.get("avgringduration"):0;//机器人振铃平均时长(秒)
			map.addAttribute("avgAiRingtime", avgAiRingtime);//机器人振铃平均时长(秒)
			
			long invitations =aggrResult.get("invitations")!=null?(long)aggrResult.get("invitations"):0;//邀约总数
			map.addAttribute("invitations", invitations);
			long qualitysubmitno =aggrResult.get("qualitysubmitno")!=null?(long)aggrResult.get("qualitysubmitno"):0;//质检失败量
			map.addAttribute("qualitysubmitno", qualitysubmitno);
			
			map.addAttribute("allduration", aiduration+agentduration);
			
			//接通率
			String answerpre = "0";
			if (calltotal!=0 && answertotal!=0) {
				answerpre = new DecimalFormat("0.00").format(((double)answertotal/(double)calltotal)*100) ;
			}
			map.addAttribute("answerpre",answerpre);
			
			//机器人平均通话时长
//			String aidurationavg = "0";
//			if (aiduration!=0 && answertotal!=0) {
//				aidurationavg = new DecimalFormat("0.00").format(((double)aiduration/(double)calltotal)) ;
//			}
//			Long aidurationavg = onlineUserRes.avgAidurationMonitor(begin, end, orgi, actid)!=null?onlineUserRes.avgAidurationMonitor(begin, end, orgi, actid):0;
			double aidurationavg =aggrResult.get("avgAidurationMonitor")!=null?(double)aggrResult.get("avgAidurationMonitor"):0;
			map.addAttribute("aidurationavg",aidurationavg);
			
			//转接率
			String aitranspre = "0";
			if (aitranstotal!=0 && answertotal!=0) {
				aitranspre = new DecimalFormat("0.00").format(((double)aitranstotal/(double)answertotal)*100) ;
			}
			map.addAttribute("aitranspre",aitranspre);
			
			//平均等待时长
			String waittingavg = "0";
			if (waittingtotal!=0 && aitranstotal!=0) {
				waittingavg = new DecimalFormat("0.00").format(((double)waittingtotal/(double)aitranstotal)) ;
			}
			map.addAttribute("waittingavg",waittingavg);
			
			//单通平均通话时长
			String onerecordtimeavg = "0";
			if (agentduration!=0 && aitranstotal!=0) {
				onerecordtimeavg = new DecimalFormat("0.00").format(((double)agentduration/(double)aitranstotal)) ;
			}
			map.addAttribute("onerecordtimeavg",onerecordtimeavg);
			
			//坐席数量
//			int totalagents = 0;
//			List<Object> agents = onlineUserRes.countAgentMonitor(begin, end, orgi, actid);
//			if (agents!=null && agents.size() >0) {
//				totalagents = agents.size();
//			}
			long totalagents =aggrResult.get("countAgentMonitor")!=null?(long)aggrResult.get("countAgentMonitor"):0;
			map.addAttribute("totalagents", totalagents);
			
			//平均成功件
			String invitationsuccessavg = "0";
			if (invitationsuccess!=0 && totalagents!=0) {
				invitationsuccessavg = new DecimalFormat("0.00").format(((double)invitationsuccess/(double)totalagents)) ;
			}
			map.addAttribute("invitationsuccessavg",invitationsuccessavg);
			
			//成功件接通比值
			String invitationsuccessanswer = "0";
			if (invitationsuccess!=0 && answertotal!=0) {
				invitationsuccessanswer = new DecimalFormat("0.00").format(((double)invitationsuccess/(double)answertotal)*100) ;
			}
			map.addAttribute("invitationsuccessanswer",invitationsuccessanswer);
			
			//成功件转人工比值
			String invitationsuccessaitrans = "0";
			if (invitationsuccess!=0 && aitranstotal!=0) {
				invitationsuccessaitrans = new DecimalFormat("0.00").format(((double)invitationsuccess/(double)aitranstotal)*100) ;
			}
			map.addAttribute("invitationsuccessaitrans",invitationsuccessaitrans);
			
			//真损率
			String transrealfaildspre = "0";
			if (answertotal!=0 && transrealfailds!=0) {
				transrealfaildspre = new DecimalFormat("0.00").format(((double)transrealfailds/(double)answertotal)*100) ;
			}
			map.addAttribute("transrealfaildspre",transrealfaildspre);
			
//			//假损率
//			String transfakefaildspre = "0";
//			if (transfailds!=0 && transfakefailds!=0) {
//				transfakefaildspre = new DecimalFormat("0.00").format(((double)transfakefailds/(double)transfailds)*100) ;
//			}
//			map.addAttribute("transfakefaildspre",transfakefaildspre);
			
			String orgi = super.getOrgi(request);
			int totalconcurrencyCache = CallOutQuene.countAiCallOutCache(orgi,null,actid);
			map.addAttribute("totalconcurrencyCache",totalconcurrencyCache);//外呼并发总数（缓存）
			int aiconcurrencyCache = 0;
			if(totalconcurrencyCache!=0){
				aiconcurrencyCache=totalconcurrencyCache-CallOutQuene.countIncallActidCallCenterAgent(orgi, actid);//机器人并发总数  = 总-人工(actid非空)
			}
			map.addAttribute("aiconcurrencyCache",aiconcurrencyCache);//机器人并发总数  = 总-人工
			
			map.addAttribute("aiusercount", CallOutQuene.getAiUserCount(orgi));//AiUser缓存数量
			
		}
		
		return request(super.createRequestPageTempletResponse("/apps/service/monitor/include/nowcall"));
	}
	
	@RequestMapping("/agent/exp")
    @Menu(type = "servicemonitor" , subtype = "exp" )
    public void statagentexp(ModelMap map , HttpServletRequest request , HttpServletResponse response ,@Valid final String actid,@Valid String begin,@Valid String end) throws Exception {
		if (UKTools.getSystemConfig().isMonitor()) {
			Map<String,Object> mapR =UKTools.getRequestParam(request);
			mapR.put("orgi",super.getOrgi(request));
			CubeReportData cubeReportData = new CubeReportData();
			List<List<ValueData>> valuedatalist =  new ArrayList<List<ValueData>>();
			Level row = new Level("root", "row" , null , 0);
			Level col = new Level("root", "col" , null , 0);
			cubeReportData.setRow(row);
			cubeReportData.setCol(col);
			row.setChilderen(new ArrayList<Level>());
			row.setTitle(new ArrayList<List<Level>>());
			row.getTitle().add(new ArrayList<Level>()) ;
			List<Level> titlesList = new ArrayList<>();
			titlesList.add( new Level("外呼通话总量", "col" , null , 0));//第二列列名
			
			List<FirstTitle> firstTitle = new ArrayList<FirstTitle>();
			firstTitle.add(new FirstTitle("坐席名", 1, false));
			firstTitle.add(new FirstTitle("外呼通话总量", 1, true));
			firstTitle.add(new FirstTitle("单通平均全程通话时长(秒)", 1, true));
			firstTitle.add(new FirstTitle("人工坐席通话总时长(小时)", 1, true));
			firstTitle.add(new FirstTitle("人工坐席通话平均时长(秒)", 1, true));
	//		firstTitle.add(new FirstTitle("振铃平均时长(秒)", 1, true));
	//		firstTitle.add(new FirstTitle("调用asr总次数", 1, true));
	//		firstTitle.add(new FirstTitle("调用asr平均次数", 1, true));
			firstTitle.add(new FirstTitle("成功件", 1, true));
			firstTitle.add(new FirstTitle("已质检总量", 1, true));
			firstTitle.add(new FirstTitle("质检成功量", 1, true));
			firstTitle.add(new FirstTitle("质检失败量", 1, true));
			firstTitle.add(new FirstTitle("未质检量", 1, true));
			firstTitle.add(new FirstTitle("质检率(%)", 1, true));
			row.setFirstTitle(firstTitle);
			Date now = new Date();
			Date begindate = !StringUtils.isBlank(begin)?UKTools.dateFormate.parse(begin):UKTools.getStartTime();
			Date enddate = !StringUtils.isBlank(end)? UKTools.dateFormate.parse(end):UKTools.getNextDay(now,1);
			List<MonitorCallout> agentList = this.getAgentList(actid, begindate, enddate, super.getOrgi(request));
			if (agentList != null && agentList.size() > 0) {
				for(MonitorCallout monitorCallout : agentList){
					List<ValueData> vdlist = new ArrayList<>();
					Level title = new Level(monitorCallout.getUsername(), "row" , null , 1);
					title.setParent(row);
					row.getTitle().get(0).add(title);
					vdlist.add(processValueData(new ValueData("callouttotals", monitorCallout.getCallouttotal(), monitorCallout.getCallouttotal(), null),title));
					vdlist.add(processValueData(new ValueData("transdurationavg", monitorCallout.getTransdurationavg(), monitorCallout.getTransdurationavg(), null),title));
					vdlist.add(processValueData(new ValueData("transdurationsum", monitorCallout.getTransdurationsum(), monitorCallout.getTransdurationsum(), null),title));
					vdlist.add(processValueData(new ValueData("agentdurationavg", monitorCallout.getAgentdurationavg(), monitorCallout.getAgentdurationavg(), null),title));
	//				vdlist.add(processValueData(new ValueData("airingdurationavg", monitorCallout.getAiringdurationavg(), monitorCallout.getAiringdurationavg(), null),title));
	//				vdlist.add(processValueData(new ValueData("aiasrtimessum", monitorCallout.getAiasrtimessum(), monitorCallout.getAiasrtimessum(), null),title));
	//				vdlist.add(processValueData(new ValueData("aiasrtimesavg", monitorCallout.getAiasrtimesavg(), monitorCallout.getAiasrtimesavg(), null),title));
					vdlist.add(processValueData(new ValueData("invitation", monitorCallout.getInvitation(), monitorCallout.getInvitation(), null),title));
					vdlist.add(processValueData(new ValueData("qualitytotal", monitorCallout.getQualitytotal(), monitorCallout.getQualitytotal(), null),title));
					vdlist.add(processValueData(new ValueData("qualitysuccess", monitorCallout.getQualitysuccess(), monitorCallout.getQualitysuccess(), null),title));
					vdlist.add(processValueData(new ValueData("qualityfail", monitorCallout.getQualityfail(), monitorCallout.getQualityfail(), null),title));
					vdlist.add(processValueData(new ValueData("qualityno", monitorCallout.getQualityno(), monitorCallout.getQualityno(), null),title));
					vdlist.add(processValueData(new ValueData("qualitypre", monitorCallout.getQualitypre(), monitorCallout.getQualitypre(), null),title));
					valuedatalist.add(vdlist);
				}
			}
			cubeReportData.setData(valuedatalist);
			
			cubeReportData.getCol().setFirstTitle(firstTitle);
			cubeReportData.getCol().setTitle(new ArrayList<List<Level>>());
			cubeReportData.getCol().getTitle().add(titlesList);
			
			response.setHeader("content-disposition", "attachment;filename=UCKeFu-Report-Monitor"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xlsx");
			new UKExcelUtil(cubeReportData , response.getOutputStream() , "坐席监控").createFile() ;
		}
		return ;
    }
	
	@RequestMapping("/ai/exp")
    @Menu(type = "servicemonitor" , subtype = "exp" )
    public void stataiexp(ModelMap map , HttpServletRequest request , HttpServletResponse response ,@Valid final String actid,@Valid String begin,@Valid String end) throws Exception {
		if (UKTools.getSystemConfig().isMonitor()) {
			Map<String,Object> mapR =UKTools.getRequestParam(request);
			mapR.put("orgi",super.getOrgi(request));
			CubeReportData cubeReportData = new CubeReportData();
			List<List<ValueData>> valuedatalist =  new ArrayList<List<ValueData>>();
			Level row = new Level("root", "row" , null , 0);
			Level col = new Level("root", "col" , null , 0);
			cubeReportData.setRow(row);
			cubeReportData.setCol(col);
			row.setChilderen(new ArrayList<Level>());
			row.setTitle(new ArrayList<List<Level>>());
			row.getTitle().add(new ArrayList<Level>()) ;
			List<Level> titlesList = new ArrayList<>();
			titlesList.add( new Level("机器人外呼总量", "col" , null , 0));
			
			List<FirstTitle> firstTitle = new ArrayList<FirstTitle>();
			firstTitle.add(new FirstTitle("机器人", 1, false));
			firstTitle.add(new FirstTitle("机器人外呼总量", 1, true));
			firstTitle.add(new FirstTitle("机器人接通总量", 1, true));
			firstTitle.add(new FirstTitle("可转人工总量", 1, true));
			firstTitle.add(new FirstTitle("转人工平均时长(秒)", 1, true));
			firstTitle.add(new FirstTitle("机器人平均通话时长(秒)", 1, true));
			firstTitle.add(new FirstTitle("振铃平均时长(秒)", 1, true));
			firstTitle.add(new FirstTitle("机器人通话总时长(小时)", 1, true));
			firstTitle.add(new FirstTitle("调用asr总次数", 1, true));
			firstTitle.add(new FirstTitle("调用asr平均次数", 1, true));
			row.setFirstTitle(firstTitle);
			Date now = new Date();
			Date begindate = !StringUtils.isBlank(begin)?UKTools.dateFormate.parse(begin):UKTools.getStartTime();
			Date enddate = !StringUtils.isBlank(end)? UKTools.dateFormate.parse(end):UKTools.getNextDay(now,1);
			List<MonitorCallout> agentList = this.getAiList(actid, begindate, enddate, super.getOrgi(request));
			if (agentList != null && agentList.size() > 0) {
				for(MonitorCallout monitorCallout : agentList){
					List<ValueData> vdlist = new ArrayList<>();
					Level title = new Level(monitorCallout.getUsername(), "row" , null , 1);
					title.setParent(row);
					row.getTitle().get(0).add(title);
					vdlist.add(processValueData(new ValueData("aitotal", monitorCallout.getAitotal(), monitorCallout.getAitotal(), null),title));
					vdlist.add(processValueData(new ValueData("aicutin", monitorCallout.getAicutin(), monitorCallout.getAicutin(), null),title));
					vdlist.add(processValueData(new ValueData("transtotal", monitorCallout.getTranstotal(), monitorCallout.getTranstotal(), null),title));
					vdlist.add(processValueData(new ValueData("aitransdurationavg", monitorCallout.getAitransdurationavg(), monitorCallout.getAitransdurationavg(), null),title));
					vdlist.add(processValueData(new ValueData("aidurationavg", monitorCallout.getAidurationavg(), monitorCallout.getAidurationavg(), null),title));
					vdlist.add(processValueData(new ValueData("airingdurationavg", monitorCallout.getAiringdurationavg(), monitorCallout.getAiringdurationavg(), null),title));
					vdlist.add(processValueData(new ValueData("aidurationsum", monitorCallout.getAidurationsum(), monitorCallout.getAidurationsum(), null),title));
					vdlist.add(processValueData(new ValueData("aiasrtimessum", monitorCallout.getAiasrtimessum(), monitorCallout.getAiasrtimessum(), null),title));
					vdlist.add(processValueData(new ValueData("aiasrtimesavg", monitorCallout.getAiasrtimesavg(), monitorCallout.getAiasrtimesavg(), null),title));
					valuedatalist.add(vdlist);
				}
			}
			cubeReportData.setData(valuedatalist);
			
			cubeReportData.getCol().setFirstTitle(firstTitle);
			cubeReportData.getCol().setTitle(new ArrayList<List<Level>>());
			cubeReportData.getCol().getTitle().add(titlesList);
			
			response.setHeader("content-disposition", "attachment;filename=UCKeFu-Report-Monitor"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xlsx");
			new UKExcelUtil(cubeReportData , response.getOutputStream() , "机器人监控").createFile() ;
		}
		return ;
    }

	public ValueData processValueData(ValueData valueData , Level row){
		if (valueData != null) {
			valueData.setRow(row);
		}
		return valueData;
	}
	
	@RequestMapping("/forecast/getnowcall")
    @Menu(type = "servicemonitor" , subtype = "getnow" )
    public ModelAndView getForecastnowcall(ModelMap map , HttpServletRequest request , String actid,Date begin,Date end) {
		map.addAttribute("actid", actid);
		Map<String,Object> aggrResult = null;
		if (UKTools.getSystemConfig().isMonitor()) {
			if (!StringUtils.isBlank(actid)) {
				aggrResult = onlineUserRes.aggrCallcenterForecastMonitor(begin, end, super.getOrgi(request),actid);
			}else{
				aggrResult = onlineUserRes.aggrCallcenterForecastMonitor(begin, end, super.getOrgi(request));
			}
		}
		if (aggrResult != null) {
			long calltotal = (long)aggrResult.get("calltotal");//通话总量
			map.addAttribute("calltotal", calltotal);
			long answertotal = (long)aggrResult.get("answertotal");//接通总量
			map.addAttribute("answertotal", answertotal);
			long aiduration =aggrResult.get("sumAidurationMonitor")!=null?(long)aggrResult.get("sumAidurationMonitor"):0;//机器人通话总时长
			map.addAttribute("aiduration", aiduration);
			long agentduration =aggrResult.get("sumAgentdurationMonitor")!=null?(long)aggrResult.get("sumAgentdurationMonitor"):0;//转人工通话总时长
			map.addAttribute("agentduration", agentduration);
			long aitranstotal = (long)aggrResult.get("aitranstotal");//转人工总量
			map.addAttribute("aitranstotal", aitranstotal);
			long waittingtotal =aggrResult.get("sumWaittimeMonitor")!=null?(long)aggrResult.get("sumWaittimeMonitor"):0;//总等待时长
			map.addAttribute("waittingtotal", waittingtotal);
			
			long sumAiRingtime = aggrResult.get("sumringduration")!=null?(long)aggrResult.get("sumringduration"):0;//机器人振铃总时长
			map.addAttribute("sumAiRingtime", sumAiRingtime!=0?UKTools.getDuration(0, sumAiRingtime*1000):"00:00:00");//机器人振铃总时长
			Double avgAiRingtime = aggrResult.get("avgringduration")!=null?(Double)aggrResult.get("avgringduration"):0;//机器人振铃平均时长(秒)
			map.addAttribute("avgAiRingtime", avgAiRingtime);//机器人振铃平均时长(秒)
			
			map.addAttribute("allduration", aiduration+agentduration);//通话总时长(机器人+人工)
			
			//接通率
			String answerpre = "0";
			if (calltotal!=0 && answertotal!=0) {
				answerpre = new DecimalFormat("0.00").format(((double)answertotal/(double)calltotal)*100) ;
			}
			map.addAttribute("answerpre",answerpre);
			
			double aidurationavg =aggrResult.get("avgAidurationMonitor")!=null?(double)aggrResult.get("avgAidurationMonitor"):0;//机器人平均通话时长
			map.addAttribute("aidurationavg",aidurationavg);
			
			//转接率
			String aitranspre = "0";
			if (aitranstotal!=0 && answertotal!=0) {
				aitranspre = new DecimalFormat("0.00").format(((double)aitranstotal/(double)answertotal)*100) ;
			}
			map.addAttribute("aitranspre",aitranspre);
			
			//平均等待时长
			String waittingavg = "0";
			if (waittingtotal!=0 && aitranstotal!=0) {
				waittingavg = new DecimalFormat("0.00").format(((double)waittingtotal/(double)aitranstotal)) ;
			}
			map.addAttribute("waittingavg",waittingavg);
			
			//单通平均通话时长
			String onerecordtimeavg = "0";
			if (agentduration!=0 && aitranstotal!=0) {
				onerecordtimeavg = new DecimalFormat("0.00").format(((double)agentduration/(double)aitranstotal)) ;
			}
			map.addAttribute("onerecordtimeavg",onerecordtimeavg);
			
			long totalagents =aggrResult.get("countAgentMonitor")!=null?(long)aggrResult.get("countAgentMonitor"):0;
			map.addAttribute("totalagents", totalagents);
			
			String orgi = super.getOrgi(request);
			int totalconcurrencyCache = CallOutQuene.countForecastCallOutCache(orgi,null,actid);
			map.addAttribute("totalconcurrencyCache",totalconcurrencyCache);//外呼并发总数（缓存）
			int aiconcurrencyCache = 0;
			if(totalconcurrencyCache!=0){
				aiconcurrencyCache=totalconcurrencyCache-CallOutQuene.countIncallActidCallCenterAgent(orgi, actid);//机器人并发总数  = 总-人工(actid非空)
			}
			map.addAttribute("aiconcurrencyCache",aiconcurrencyCache);//机器人并发总数  = 总-人工
			
			map.addAttribute("aiusercount", CallOutQuene.getAiUserCount(orgi));//AiUser缓存数量
			
		}
		
		return request(super.createRequestPageTempletResponse("/apps/service/monitor/include/nowcall"));
	}
	
	/**
	 * 预测式外呼-坐席列表
	 * @param actid
	 * @param begindate
	 * @param enddate
	 * @param orgi
	 * @return
	 */
	public List<MonitorCallout> getForecastAgentList(final String actid,Date begindate,Date enddate,String orgi){
		List<MonitorCallout> agentList = new ArrayList<>();
		if (UKTools.getSystemConfig().isMonitor()) {
			List<Object> result1 = onlineUserRes.aggrForecastGroupbyUsername(begindate,enddate,orgi,actid);
			if (result1 != null && result1.size() > 0) {
				for(Object re : result1){
					Object[] res = (Object[]) re;
					MonitorCallout mc = new MonitorCallout();
					mc.setUsertype("agent");
					mc.setUsername(res[0].toString());
					mc.setCallouttotal(res[1].toString());
					mc.setTransdurationavg(res[2].toString());
					if (res[3]!=null && !StringUtils.isBlank(res[3].toString())) {
						if (!res[3].toString().equals("0")) {
							mc.setTransdurationsum(UKTools.getDuration(0, Long.parseLong(res[3].toString())));
						}else{
							mc.setTransdurationsum("0");
						}
					}
					mc.setAiringdurationavg(res[4].toString());
					mc.setAiasrtimessum(res[5].toString());
					mc.setAiasrtimesavg(res[6].toString());
					agentList.add(mc);
				}
			}
		}
		return agentList;
	}
	
	/**
	 * 预测式外呼-技能组列表
	 * @param actid
	 * @param begindate
	 * @param enddate
	 * @param orgi
	 * @return
	 */
	public List<MonitorCallout> getForecastSkillList(final String actid,Date begindate,Date enddate,String orgi){
		List<MonitorCallout> aiList = new ArrayList<>();
		if (UKTools.getSystemConfig().isMonitor()) {
			List<Object> result2 = onlineUserRes.aggrForecastGroupbySkill(begindate,enddate, orgi,actid);
			if (result2 != null && result2.size() > 0) {
				for(Object re : result2){
					Object[] res = (Object[]) re;
					MonitorCallout mc = new MonitorCallout();
					mc.setUsertype("skill");
					mc.setUsername(res[0].toString());
					mc.setAitotal(res[1].toString());
					mc.setAidurationavg(res[2]!=null ? res[2].toString():"0");
					mc.setAiringdurationavg(res[3].toString());
					if (res[4]!=null && !StringUtils.isBlank(res[4].toString())) {
						if (!res[4].toString().equals("0")) {
							mc.setAidurationsum(UKTools.getDuration(0, Long.parseLong(res[4].toString())));
						}else{
							mc.setAidurationsum("0");
						}
					}
					mc.setAiasrtimessum(res[5].toString());
					mc.setAiasrtimesavg(res[6]!=null ? res[6].toString():"0");
					mc.setAicutin(res[7].toString());
					aiList.add(mc);
				}
			}
		}
		return aiList;
	}
	
	@RequestMapping("/forecast/agent/exp")
    @Menu(type = "servicemonitor" , subtype = "exp" )
    public void forecaagentexp(ModelMap map , HttpServletRequest request , HttpServletResponse response ,@Valid final String actid,@Valid String begin,@Valid String end) throws Exception {
		if (UKTools.getSystemConfig().isMonitor()) {
			Map<String,Object> mapR =UKTools.getRequestParam(request);
			mapR.put("orgi",super.getOrgi(request));
			CubeReportData cubeReportData = new CubeReportData();
			List<List<ValueData>> valuedatalist =  new ArrayList<List<ValueData>>();
			Level row = new Level("root", "row" , null , 0);
			Level col = new Level("root", "col" , null , 0);
			cubeReportData.setRow(row);
			cubeReportData.setCol(col);
			row.setChilderen(new ArrayList<Level>());
			row.setTitle(new ArrayList<List<Level>>());
			row.getTitle().add(new ArrayList<Level>()) ;
			List<Level> titlesList = new ArrayList<>();
			titlesList.add( new Level("外呼通话总量", "col" , null , 0));//第二列列名
			
			List<FirstTitle> firstTitle = new ArrayList<FirstTitle>();
			firstTitle.add(new FirstTitle("坐席名", 1, false));
			firstTitle.add(new FirstTitle("外呼通话总量", 1, true));
			firstTitle.add(new FirstTitle("单通平均全程通话时长(秒)", 1, true));
			firstTitle.add(new FirstTitle("人工坐席通话总时长(小时)", 1, true));
			firstTitle.add(new FirstTitle("人工坐席通话平均时长(秒)", 1, true));
			row.setFirstTitle(firstTitle);
			Date now = new Date();
			Date begindate = !StringUtils.isBlank(begin)?UKTools.dateFormate.parse(begin):UKTools.getStartTime();
			Date enddate = !StringUtils.isBlank(end)? UKTools.dateFormate.parse(end):UKTools.getNextDay(now,1);
			List<MonitorCallout> agentList = this.getForecastAgentList(actid, begindate, enddate, super.getOrgi(request));
			if (agentList != null && agentList.size() > 0) {
				for(MonitorCallout monitorCallout : agentList){
					List<ValueData> vdlist = new ArrayList<>();
					Level title = new Level(monitorCallout.getUsername(), "row" , null , 1);
					title.setParent(row);
					row.getTitle().get(0).add(title);
					vdlist.add(processValueData(new ValueData("callouttotals", monitorCallout.getCallouttotal(), monitorCallout.getCallouttotal(), null),title));
					vdlist.add(processValueData(new ValueData("transdurationavg", monitorCallout.getTransdurationavg(), monitorCallout.getTransdurationavg(), null),title));
					vdlist.add(processValueData(new ValueData("transdurationsum", monitorCallout.getTransdurationsum(), monitorCallout.getTransdurationsum(), null),title));
					vdlist.add(processValueData(new ValueData("agentdurationavg", monitorCallout.getAgentdurationavg(), monitorCallout.getAgentdurationavg(), null),title));
					valuedatalist.add(vdlist);
				}
			}
			cubeReportData.setData(valuedatalist);
			
			cubeReportData.getCol().setFirstTitle(firstTitle);
			cubeReportData.getCol().setTitle(new ArrayList<List<Level>>());
			cubeReportData.getCol().getTitle().add(titlesList);
			
			response.setHeader("content-disposition", "attachment;filename=UCKeFu-Report-Monitor"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xlsx");
			new UKExcelUtil(cubeReportData , response.getOutputStream() , "预测式外呼-坐席监控").createFile() ;
		}
		return ;
    }
	
	@RequestMapping("/forecast/skill/exp")
    @Menu(type = "servicemonitor" , subtype = "exp" )
    public void forecastskillexp(ModelMap map , HttpServletRequest request , HttpServletResponse response ,@Valid final String actid,@Valid String begin,@Valid String end) throws Exception {
		if (UKTools.getSystemConfig().isMonitor()) {
			Map<String,Object> mapR =UKTools.getRequestParam(request);
			mapR.put("orgi",super.getOrgi(request));
			CubeReportData cubeReportData = new CubeReportData();
			List<List<ValueData>> valuedatalist =  new ArrayList<List<ValueData>>();
			Level row = new Level("root", "row" , null , 0);
			Level col = new Level("root", "col" , null , 0);
			cubeReportData.setRow(row);
			cubeReportData.setCol(col);
			row.setChilderen(new ArrayList<Level>());
			row.setTitle(new ArrayList<List<Level>>());
			row.getTitle().add(new ArrayList<Level>()) ;
			List<Level> titlesList = new ArrayList<>();
			titlesList.add( new Level("技能组外呼总量", "col" , null , 0));
			
			List<FirstTitle> firstTitle = new ArrayList<FirstTitle>();
			firstTitle.add(new FirstTitle("技能组", 1, false));
			firstTitle.add(new FirstTitle("技能组外呼总量", 1, true));
			firstTitle.add(new FirstTitle("技能组接通总量", 1, true));
			firstTitle.add(new FirstTitle("技能组平均通话时长(秒)", 1, true));
			firstTitle.add(new FirstTitle("振铃平均时长(秒)", 1, true));
			firstTitle.add(new FirstTitle("技能组通话总时长(小时)", 1, true));
			firstTitle.add(new FirstTitle("调用asr总次数", 1, true));
			firstTitle.add(new FirstTitle("调用asr平均次数", 1, true));
			row.setFirstTitle(firstTitle);
			Date now = new Date();
			Date begindate = !StringUtils.isBlank(begin)?UKTools.dateFormate.parse(begin):UKTools.getStartTime();
			Date enddate = !StringUtils.isBlank(end)? UKTools.dateFormate.parse(end):UKTools.getNextDay(now,1);
			List<MonitorCallout> agentList = this.getForecastSkillList(actid, begindate, enddate, super.getOrgi(request));
			if (agentList != null && agentList.size() > 0) {
				for(MonitorCallout monitorCallout : agentList){
					List<ValueData> vdlist = new ArrayList<>();
					Level title = new Level(monitorCallout.getUsername(), "row" , null , 1);
					title.setParent(row);
					row.getTitle().get(0).add(title);
					vdlist.add(processValueData(new ValueData("aitotal", monitorCallout.getAitotal(), monitorCallout.getAitotal(), null),title));
					vdlist.add(processValueData(new ValueData("aicutin", monitorCallout.getAicutin(), monitorCallout.getAicutin(), null),title));
					vdlist.add(processValueData(new ValueData("aidurationavg", monitorCallout.getAidurationavg(), monitorCallout.getAidurationavg(), null),title));
					vdlist.add(processValueData(new ValueData("airingdurationavg", monitorCallout.getAiringdurationavg(), monitorCallout.getAiringdurationavg(), null),title));
					vdlist.add(processValueData(new ValueData("aidurationsum", monitorCallout.getAidurationsum(), monitorCallout.getAidurationsum(), null),title));
					vdlist.add(processValueData(new ValueData("aiasrtimessum", monitorCallout.getAiasrtimessum(), monitorCallout.getAiasrtimessum(), null),title));
					vdlist.add(processValueData(new ValueData("aiasrtimesavg", monitorCallout.getAiasrtimesavg(), monitorCallout.getAiasrtimesavg(), null),title));
					valuedatalist.add(vdlist);
				}
			}
			cubeReportData.setData(valuedatalist);
			
			cubeReportData.getCol().setFirstTitle(firstTitle);
			cubeReportData.getCol().setTitle(new ArrayList<List<Level>>());
			cubeReportData.getCol().getTitle().add(titlesList);
			
			response.setHeader("content-disposition", "attachment;filename=UCKeFu-Report-Monitor"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())+".xlsx");
			new UKExcelUtil(cubeReportData , response.getOutputStream() , "预测式外呼-技能组监控").createFile() ;
		}
		return ;
    }
}